/**
 * @file 1config-operator-overloading.cpp
 * @author Kun (kun_g@msn.com)
 * @brief << operator overloaded
 * @version 0.1
 * @date 2024-05-14
 *
 * @copyright Copyright (c) 2024
 *
 */
#include <iostream>
using namespace std;

class INT {
  friend ostream &operator<<(ostream &os, const INT &i);

public:
  INT(int i) : m_i(i) {};

  // prefix: increment and then fetch
  INT &operator++() {
    ++(this->m_i);
    return *this;
  }

  // postfix: fetch and then increment
  const INT operator++(int) {
    INT temp = *this;
    ++(*this); // same with (*this)++
    return temp;
  }

  INT &operator--() {
    --(this->m_i);
    return *this;
  }

  const INT operator--(int) {
    INT temp = *this;
    --(*this);
    return temp;
  }

  int &operator*() const { return (int &)m_i; }

private:
  int m_i;
};

ostream &operator<<(ostream &os, const INT &i) {
  os << '[' << i.m_i << ']';
  return os;
}

int main() {
  INT I(5);
  cout << I++;
  cout << ++I;
  cout << I--;
  cout << --I;
  cout << *I;
}